package com.coffee.netty.config;

import lombok.Setter;

import java.util.Optional;

/**
 * get configs through system properties prior to default value
 * @author songkui
 * @since 2024/7/30
 */
@Setter
public class ConfigManager {

    private ServerProperties serverProperties;

    private static final class ManagerHolder {
        static final ConfigManager manager = new ConfigManager();
    }

    public static ConfigManager getInstance() {
        return ManagerHolder.manager;
    }

    public int port(){
        return serverProperties.getPort();
    }

    public String inetHost(){
        return serverProperties.getInetHost();
    }

    public Long heartbeatSecond(){
        return serverProperties.getHeartbeatSecond();
    }


    /**
     * TCP.nodelay : true
     * TCP.SO_REUSEADDR : true
     * TCP.SO_BACKLOG : 1024
     * TCP.SO_KEEPALIVE :
     * TCP.IO_RATIO
     * TCP.NETTY_BUFFER_POOLED
     */
    public static boolean tcp_nodelay() {
        return getBool(Configs.TCP_NODELAY, Configs.TCP_NODELAY_DEFAULT);
    }

    public static boolean tcp_so_reuseaddr() {
        return getBool(Configs.TCP_SO_REUSEADDR, Configs.TCP_SO_REUSEADDR_DEFAULT);
    }

    public static int tcp_so_backlog() {
        return getInt(Configs.TCP_SO_BACKLOG, Configs.TCP_SO_BACKLOG_DEFAULT);
    }

    public static boolean tcp_so_keepalive() {
        return getBool(Configs.TCP_SO_KEEPALIVE, Configs.TCP_SO_KEEPALIVE_DEFAULT);
    }

    public static int netty_io_ratio() {
        return getInt(Configs.NETTY_IO_RATIO, Configs.NETTY_IO_RATIO_DEFAULT);
    }

    public static boolean netty_buffer_pooled() {
        return getBool(Configs.NETTY_BUFFER_POOLED, Configs.NETTY_BUFFER_POOLED_DEFAULT);
    }

    public static int netty_buffer_low_watermark() {
        return getInt(Configs.NETTY_BUFFER_LOW_WATERMARK,
            Configs.NETTY_BUFFER_LOW_WATERMARK_DEFAULT);
    }

    public static int netty_buffer_high_watermark() {
        return getInt(Configs.NETTY_BUFFER_HIGH_WATERMARK,
            Configs.NETTY_BUFFER_HIGH_WATERMARK_DEFAULT);
    }

    public static boolean netty_epoll() {
        return getBool(Configs.NETTY_EPOLL_SWITCH, Configs.NETTY_EPOLL_SWITCH_DEFAULT);
    }


    public static Integer tcp_so_sndbuf() {
        return getInteger(Configs.TCP_SO_SNDBUF, null);
    }

    public static Integer tcp_so_rcvbuf() {
        return getInteger(Configs.TCP_SO_RCVBUF, null);
    }



    public static boolean netty_epoll_lt_enabled() {
        return getBool(Configs.NETTY_EPOLL_LT, Configs.NETTY_EPOLL_LT_DEFAULT);
    }

    // ~~~ properties for idle 空闲属性
    public static boolean tcp_idle_switch() {
        return getBool(Configs.TCP_IDLE_SWITCH, Configs.TCP_IDLE_SWITCH_DEFAULT);
    }

    public static int tcp_idle() {
        return getInt(Configs.TCP_IDLE, Configs.TCP_IDLE_DEFAULT);
    }

    public static int tcp_idle_maxtimes() {
        return getInt(Configs.TCP_IDLE_MAXTIMES, Configs.TCP_IDLE_MAXTIMES_DEFAULT);
    }

    public static long tcp_server_idle() {
        return Optional.ofNullable(ConfigManager.getInstance().heartbeatSecond()).orElse(0L) > 1L ? ConfigManager.getInstance().heartbeatSecond() : getInt(Configs.TCP_SERVER_IDLE, Configs.TCP_SERVER_IDLE_DEFAULT);
    }

    // ~~~ properties for connection manager 连接管理器的属性
    public static int conn_create_tp_min_size() {
        return getInt(Configs.CONN_CREATE_TP_MIN_SIZE, Configs.CONN_CREATE_TP_MIN_SIZE_DEFAULT);
    }

    public static int conn_create_tp_max_size() {
        return getInt(Configs.CONN_CREATE_TP_MAX_SIZE, Configs.CONN_CREATE_TP_MAX_SIZE_DEFAULT);
    }

    public static int conn_create_tp_queue_size() {
        return getInt(Configs.CONN_CREATE_TP_QUEUE_SIZE, Configs.CONN_CREATE_TP_QUEUE_SIZE_DEFAULT);
    }

    public static int conn_create_tp_keepalive() {
        return getInt(Configs.CONN_CREATE_TP_KEEPALIVE_TIME,
            Configs.CONN_CREATE_TP_KEEPALIVE_TIME_DEFAULT);
    }

    public static Integer getInteger(final String key, final String defaultValue) {
        String value = System.getProperty(key, null);
        return value != null ? Integer.parseInt(value) : null;
    }


    // ~~~ properties for processor manager 处理器管理器的属性
    public static int default_tp_min_size() {
        return getInt(Configs.TP_MIN_SIZE, Configs.TP_MIN_SIZE_DEFAULT);
    }

    public static int default_cpu_size() {
        return getInt(Configs.TP_CPU_SIZE, Configs.TP_CPU_SIZE_DEFAULT);
    }

    public static int default_ep_size() {
        return getInt(Configs.EP_CPU_SIZE, Configs.EP_CPU_SIZE_DEFAULT);
    }

    public static int default_tsp_min_size(){
        return getInt(Configs.TSP_MIN_SIZE, Configs.TSP_MIN_SIZE_DEFAULT);
    }

    public static int default_tp_max_size() {
        return getInt(Configs.TP_MAX_SIZE, Configs.TP_MAX_SIZE_DEFAULT);
    }

    public static int default_tp_queue_size() {
        return getInt(Configs.TP_QUEUE_SIZE, Configs.TP_QUEUE_SIZE_DEFAULT);
    }

    public static int default_tp_keepalive_time() {
        return getInt(Configs.TP_KEEPALIVE_TIME, Configs.TP_KEEPALIVE_TIME_DEFAULT);
    }

    // ~~~ properties for reconnect manager 重新连接管理器的属性
    public static boolean conn_reconnect_switch() {
        return getBool(Configs.CONN_RECONNECT_SWITCH, Configs.CONN_RECONNECT_SWITCH_DEFAULT);
    }

    // ~~~ properties for connection monitor 连接监视器的属性
    public static boolean conn_monitor_switch() {
        return getBool(Configs.CONN_MONITOR_SWITCH, Configs.CONN_MONITOR_SWITCH_DEFAULT);
    }

    public static long conn_monitor_initial_delay() {
        return getLong(Configs.CONN_MONITOR_INITIAL_DELAY,
            Configs.CONN_MONITOR_INITIAL_DELAY_DEFAULT);
    }

    public static long conn_monitor_period() {
        return getLong(Configs.CONN_MONITOR_PERIOD, Configs.CONN_MONITOR_PERIOD_DEFAULT);
    }

    public static int conn_threshold() {
        return getInt(Configs.CONN_THRESHOLD, Configs.CONN_THRESHOLD_DEFAULT);
    }

    public static int retry_detect_period() {
        return getInt(Configs.RETRY_DETECT_PERIOD, Configs.RETRY_DETECT_PERIOD_DEFAULT);
    }

    // ~~~ properties for serializer 序列化程序的属性
//    public static final byte serializer = serializer();

//    public static byte serializer() {
//        return getByte(Configs.SERIALIZER, Configs.SERIALIZER_DEFAULT);
//    }

    // ~~~ public helper methods to retrieve system property 用于检索系统属性的公共帮助方法
    public static boolean getBool(String key, String defaultValue) {
        return Boolean.parseBoolean(System.getProperty(key, defaultValue));
    }

    public static int getInt(String key, String defaultValue) {
        return Integer.parseInt(System.getProperty(key, defaultValue));
    }

    public static byte getByte(String key, String defaultValue) {
        return Byte.parseByte(System.getProperty(key, defaultValue));
    }

    public static long getLong(String key, String defaultValue) {
        return Long.parseLong(System.getProperty(key, defaultValue));
    }
}